﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.SessionState;
using Fadada.OpenAPI.Events;

namespace Fadada.OpenAPI
{
    /// <summary>
    /// 异步通知总控制器
    /// </summary>
    public abstract class IEventProcess: IHttpHandler
    {
        protected HttpContext Context;


        protected abstract string GetAppKey();

        protected abstract void ProcessRequest_Before();

        public void ProcessRequest(HttpContext context)
        {
            this.Context = context;
            ProcessRequest_Before();
            ValidateSign(context.Request);

            var eventName = context.Request.Headers["X-FDD-Api-Event"];
            var eventType = Utils.ClassTypeUtils.FindType(typeof(IEvent).Namespace + "." + eventName + "Event");
            if (eventType == null || typeof(IEvent).IsAssignableFrom(eventType) == false)
            {
                throw new Exception("未找到对应事件");
            }         

            var bizContent = context.Request.Form["bizContent"];
            var eventModel = JsonConvert.DeserializeObject(bizContent, eventType);
            var eventHandlerTypes = Utils.ClassTypeUtils.FindImplementedTypes(typeof(IEventHandler<>).MakeGenericType(eventType));
            foreach (var handlerType in eventHandlerTypes)
            {
                var handler = Utils.ClassTypeUtils.Instance(handlerType);
                handlerType.GetMethod("Handler").Invoke(handler, new[] { eventModel });
            }
            context.Response.Write("success");
        }


        public bool IsReusable
        {
            get
            {
                return true;
            }
        }

        public void ValidateSign(HttpRequest request)
        {
            var timestamp = request.Headers["X-FDD-Api-Timestamp"];
            var headerParames = new Dictionary<string, string>();
            headerParames.Add("X-FDD-Api-App-Id", request.Headers["X-FDD-Api-App-Id"]);
            headerParames.Add("X-FDD-Api-Sign-Type", request.Headers["X-FDD-Api-Sign-Type"]);
            headerParames.Add("X-FDD-Api-Timestamp", timestamp);
            headerParames.Add("X-FDD-Api-Nonce", request.Headers["X-FDD-Api-Nonce"]);
            headerParames.Add("X-FDD-Api-Event", request.Headers["X-FDD-Api-Event"]);
            headerParames.Add("bizContent", request.Form["bizContent"]);
            foreach (var p in headerParames)
            {
                if (string.IsNullOrEmpty(p.Value)) throw new Exception(p.Key + "不能为空");
            }
            var ret = request.Headers["X-FDD-Api-Sign"] == Utils.SignUtil.GetSign(headerParames, timestamp, GetAppKey());
            if (ret == false) throw new Exception("签名错误");
        }
    }
}